package main

import (
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/ethereum/go-ethereum/accounts/keystore"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/internal/flags"
	"github.com/urfave/cli/v2"
)

// Version version of this build
var Version = "v0.1"

var (
	pkfFlag = &cli.StringFlag{
		Name:  "private-key-file",
		Usage: "the private-key file name(full name).",
		Value: "UTC--xxxx-xx-xxxxx-xx-xx.xxxxxxxxxx--xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
	}
	pwFlag = &cli.StringFlag{
		Name:  "password",
		Usage: "the password to unlock the private-key file.",
		Value: "***",
	}
)

var app = flags.NewApp("keystore2privatekey")

func init() {
	app.Name = "Keystore2privatekey"

	app.Flags = []cli.Flag{
		pkfFlag,
		pwFlag,
	}
	app.Action = Keystore2privatekey

	app.Version = Version
}

func Keystore2privatekey(ctx *cli.Context) error {
	privateKeyFile := ctx.String("private-key-file")
	passwd := ctx.String("password")
	privKey, address, err := KeystoreToPrivateKey(privateKeyFile, passwd)
	if err != nil {
		fmt.Printf("quit with err : %s\n", err.Error())
		os.Exit(-1)
	}
	fmt.Println("**********************************************************************")
	fmt.Printf("privKey:[%s]\naddress:[%s]\n", privKey, address)
	fmt.Println("**********************************************************************")
	return nil
}

func KeystoreToPrivateKey(privateKeyFile, password string) (string, string, error) {
	keyjson, err := ioutil.ReadFile(privateKeyFile)
	if err != nil {
		fmt.Println("read keyjson file failed：", err)
	}
	unlockedKey, err := keystore.DecryptKey(keyjson, password)
	if err != nil {

		return "", "", err

	}
	privKey := hex.EncodeToString(unlockedKey.PrivateKey.D.Bytes())
	addr := crypto.PubkeyToAddress(unlockedKey.PrivateKey.PublicKey)
	return privKey, addr.String(), nil
}

func main() {

	err := app.Run(os.Args)
	if err != nil {
		os.Exit(-1)
	}
}
